import * as THREE from 'three';
import { Vec3 } from '@/core/types';
import { BlockType } from '@/blocks/types';

export class RedstoneVisualEffects {
  private scene: THREE.Scene;
  private effects: Map<string, THREE.Object3D> = new Map();

  constructor(scene: THREE.Scene) {
    this.scene = scene;
  }

  public createRedstoneWireEffect(position: Vec3, powerLevel: number): void {
    const key = this.getPositionKey(position);
    
    // 移除旧效果
    this.removeEffect(key);
    
    if (powerLevel > 0) {
      // 创建发光的红石线效果
      const geometry = new THREE.PlaneGeometry(0.8, 0.8);
      const intensity = powerLevel / 15;
      const color = new THREE.Color().setHSL(0, 1, 0.3 + intensity * 0.4); // 从暗红到亮红
      
      const material = new THREE.MeshBasicMaterial({
        color: color,
        transparent: true,
        opacity: 0.8,
        side: THREE.DoubleSide
      });
      
      const mesh = new THREE.Mesh(geometry, material);
      mesh.position.set(position.x + 0.5, position.y + 0.01, position.z + 0.5);
      mesh.rotation.x = -Math.PI / 2; // 平放在地面上
      
      // 添加发光效果
      if (intensity > 0.5) {
        const glowGeometry = new THREE.PlaneGeometry(1.2, 1.2);
        const glowMaterial = new THREE.MeshBasicMaterial({
          color: color,
          transparent: true,
          opacity: 0.3,
          side: THREE.DoubleSide
        });
        
        const glow = new THREE.Mesh(glowGeometry, glowMaterial);
        glow.position.copy(mesh.position);
        glow.rotation.copy(mesh.rotation);
        mesh.add(glow);
      }
      
      this.scene.add(mesh);
      this.effects.set(key, mesh);
    }
  }

  public createRedstoneTorchEffect(position: Vec3, isActive: boolean): void {
    const key = this.getPositionKey(position);
    
    // 移除旧效果
    this.removeEffect(key);
    
    if (isActive) {
      // 创建红石火把的发光效果
      const geometry = new THREE.SphereGeometry(0.3, 8, 8);
      const material = new THREE.MeshBasicMaterial({
        color: 0xFF4500,
        transparent: true,
        opacity: 0.6
      });
      
      const mesh = new THREE.Mesh(geometry, material);
      mesh.position.set(position.x + 0.5, position.y + 0.8, position.z + 0.5);
      
      // 添加粒子效果
      this.addParticleEffect(mesh, 0xFF4500);
      
      this.scene.add(mesh);
      this.effects.set(key, mesh);
    }
  }

  private addParticleEffect(parent: THREE.Object3D, color: number): void {
    const particleCount = 10;
    const geometry = new THREE.BufferGeometry();
    const positions = new Float32Array(particleCount * 3);
    
    for (let i = 0; i < particleCount; i++) {
      positions[i * 3] = (Math.random() - 0.5) * 0.5;
      positions[i * 3 + 1] = Math.random() * 0.5;
      positions[i * 3 + 2] = (Math.random() - 0.5) * 0.5;
    }
    
    geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
    
    const material = new THREE.PointsMaterial({
      color: color,
      size: 0.05,
      transparent: true,
      opacity: 0.8
    });
    
    const particles = new THREE.Points(geometry, material);
    parent.add(particles);
    
    // 简单的粒子动画
    const animate = () => {
      if (particles.parent) {
        particles.rotation.y += 0.01;
        const positions = particles.geometry.attributes.position.array as Float32Array;
        
        for (let i = 0; i < particleCount; i++) {
          positions[i * 3 + 1] += 0.002;
          if (positions[i * 3 + 1] > 0.5) {
            positions[i * 3 + 1] = 0;
          }
        }
        
        particles.geometry.attributes.position.needsUpdate = true;
        requestAnimationFrame(animate);
      }
    };
    
    animate();
  }

  public updateEffect(position: Vec3, blockType: BlockType, powerLevel: number): void {
    switch (blockType) {
      case BlockType.REDSTONE_WIRE:
        this.createRedstoneWireEffect(position, powerLevel);
        break;
      case BlockType.REDSTONE_TORCH:
        this.createRedstoneTorchEffect(position, powerLevel > 0);
        break;
    }
  }

  public removeEffect(key: string): void {
    const effect = this.effects.get(key);
    if (effect) {
      this.scene.remove(effect);
      
      // 清理资源
      effect.traverse((child) => {
        if (child instanceof THREE.Mesh) {
          if (child.geometry) {
            child.geometry.dispose();
          }
          if (child.material) {
            if (Array.isArray(child.material)) {
              child.material.forEach(mat => mat.dispose());
            } else {
              child.material.dispose();
            }
          }
        }
      });
      
      this.effects.delete(key);
    }
  }

  public removeEffectAt(position: Vec3): void {
    const key = this.getPositionKey(position);
    this.removeEffect(key);
  }

  private getPositionKey(position: Vec3): string {
    return `${Math.floor(position.x)},${Math.floor(position.y)},${Math.floor(position.z)}`;
  }

  public clear(): void {
    for (const key of this.effects.keys()) {
      this.removeEffect(key);
    }
  }

  public getEffectCount(): number {
    return this.effects.size;
  }
}